/*
	File:		Saw.h
	Author:		Ben Feldmann
	Purpose:	Class for managing the buzzsaw weapon
*/


#include "Saw.h"
#include "ObjectManager.h"
#include "GamePlayState.h"
#include "EventSystem.h"
#include "Game.h"
#include "Tile.h"

#include "SGD Wrappers/CSGD_TextureManager.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_XAudio2.h"


Saw::Saw(Player* owner)
{
	isAttacking		= false;
	isSpcAttacking	= false;
	canSpcAttack	= true;
	returning		= false;
	hitEnemy		= false;
	
	atkTimer		= 0.0f;
	spcAtkTimer		= 0.0f;

	persist			= false;
	persistTimer	= 0;
	persistDuration = 1.0f;
	damageRate		= 0.5f;
	curDamageTime	= 0;

	SetTextureID(CSGD_TextureManager::GetInstance()->LoadTexture(_T("Graphics/saw.png")));

	SetOwner(owner);
	SetDamage(20.0f);
	SetSpcDamage(60.0f);
	SetCoolTimer(0.0f);
	SetCoolSeconds(10.0f); // Test Variable
	SetAtkSpeed(0.5f);
	SetEnergyCost(10.0f);
	SetMetalPrice(100);
	SetCircuitPrice(50);
	SetX(GetOwner()->GetX());
	SetY(GetOwner()->GetY());
	SetHeight(16);
	SetWidth(16);


	meleeType = MW_SAW;
	type	  = OBJ_WEAPON;

	ObjectManager::GetInstance()->AddObject(this);
	Release();

	hitParticle  = Emitter::LoadEmitter("Emitters/hitParticle.xml");

	//sawAttack = CSGD_XAudio2::GetInstance()->SFXLoadSound(_T("Sound/Melee Weapons/sawAttack.wav"));
}

Saw::~Saw()
{
	if(GetTextureID() != -1 )
	{
		CSGD_TextureManager::GetInstance()->UnloadTexture(GetTextureID());
		SetTextureID(-1);
	}
	//if(sawAttack != -1)
	//{
	//	CSGD_XAudio2::GetInstance()->SFXStopSound(sawAttack);
	//	CSGD_XAudio2::GetInstance()->SFXUnloadSound(sawAttack);
	//	sawAttack = -1;
	//}

	ObjectManager::GetInstance()->RemoveObject(this);
}

bool Saw::CheckCollision(IEntity* base) 
{
	if(Entity::CheckCollision(base) == true && base != this->GetOwner() && base->GetType() != OBJ_PICKUP && base->GetType() != OBJ_WEAPON)
	{
		/*if(base->GetType() == OBJ_TILE && dynamic_cast<Tile*>(base)->GetSolid() == true)
			returning = true;*/

		if(GetOwner()->GetClock() == false && base->GetType() == OBJ_ENEMY)
		{
			if(isAttacking == true && hitEnemy == false)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetDamage()));

				dynamic_cast<Enemy*>(base)->SetDOT(3.0f, 1.0f, 0.5f);

				hitParticle->SetPosition((GetX()+GetWidth()) - GamePlayState::GetInstance()->GetCamX(), (GetY()+GetHeight()/2.0f) - GamePlayState::GetInstance()->GetCamY());
				hitParticle->Burst();	
				hitEnemy = true;

				return true;
			}
			else if(isSpcAttacking == true && hitEnemy == false)
			{
				persist = true;
				hitEnemy = true;
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetSpcDamage()));
				dynamic_cast<Enemy*>(base)->SetDOT(3.0f, 2.5f, 0.5f);
				hitParticle->SetPosition((GetX()+GetWidth()) - GamePlayState::GetInstance()->GetCamX(), (GetY()+GetHeight()/2.0f) - GamePlayState::GetInstance()->GetCamY());
				hitParticle->Burst();
				CSGD_XAudio2::GetInstance()->SFXPlaySound(GetOwner()->GetSawSound());

				return true;
			}
			else
				return false;
		}
		else if (GetOwner()->GetClock() == true && base->GetType() == OBJ_ENEMY)
		{
			if(isAttacking == true && hitEnemy == false)
			{
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetDamage()*1.5f));
				hitParticle->SetPosition((GetX()+GetWidth()) - GamePlayState::GetInstance()->GetCamX(), (GetY()+GetHeight()/2.0f) - GamePlayState::GetInstance()->GetCamY());
				hitParticle->Burst();
				hitEnemy = true;

				return true;
			}
			else if(isSpcAttacking == true && hitEnemy == false)
			{
				persist = true;
				hitEnemy = true;
				EventSystem::GetInstance()->SendEvent("target_hit", base, new float(GetSpcDamage()*1.5f));
				hitParticle->SetPosition((GetX()+GetWidth()) - GamePlayState::GetInstance()->GetCamX(), (GetY()+GetHeight()/2.0f) - GamePlayState::GetInstance()->GetCamY());
				hitParticle->Burst();
				CSGD_XAudio2::GetInstance()->SFXPlaySound(GetOwner()->GetSawSound());

				return true;
			}
			else
				return false;
		}
		else 
			return false;
	}
	else
		return false;
}

void Saw::Attack() 
{
	if(isAttacking == false)
	{
		weaponAnimation[GetDirection()].Play();
		isAttacking = true;
		//attackReady = false;
		//CSGD_XAudio2::GetInstance()->SFXPlaySound(sawAttack);
	}
}

void Saw::SpecialAttack() 
{
	if(canSpcAttack == true)// && spcAttacked == false)
	{
		canSpcAttack = false;
		render = true;
		hitEnemy = false;
		isSpcAttacking = true;
		weaponAnimation[GetDirection()].Play();
		GetOwner()->SetEnergy(GetOwner()->GetEnergy() - GetEnergyCost());
		spcAtkTimer = 0.0f;
		SetCoolTimer(spcAtkTimer);
	}
}

void Saw::Update(float elapsed)
{
	hitParticle->Update(elapsed);

	if(persist == true)
	{
		persistTimer += elapsed;

		if(persistTimer >= curDamageTime && persistTimer <= persistDuration)
		{
			curDamageTime += damageRate;
			hitEnemy = false;
		}
		if(persistTimer > persistDuration)
		{
			returning = true;
			persist = false;
			persistTimer = 0;
		}
	}

	if(isSpcAttacking == false)
	{
		SetDirection(GetOwner()->GetDirection());
		SetX(GetOwner()->GetX() + (GetOwner()->GetWidth()/2.0f) + 5);
		SetY(GetOwner()->GetY() + (GetOwner()->GetHeight()/2.0f) + 11);
	}

	if(GetOwner()->GetAnimation() != &weaponAnimation[GetDirection()])
	{
		GetOwner()->SetAnimation(&weaponAnimation[GetDirection()]);
	}


	if(isAttacking == true)
	{
		atkTimer += elapsed;

		if(atkTimer >= GetAtkSpeed())
		{
			isAttacking = false;
			atkTimer = 0.0f;
			hitEnemy = false;
		}
	}

	if(canSpcAttack == false)
	{
		spcAtkTimer += elapsed;

		SetCoolTimer(spcAtkTimer);

		if(spcAtkTimer >= GetCoolSeconds())
		{
			canSpcAttack = true;
			isSpcAttacking = false;
			returning = false;
			hitEnemy = false;
			render = false;
		}

		if(isSpcAttacking == false)
			return;

		if(spcAtkTimer >= 0.75f && persist == false)
		{
			returning = true;
		}

		if(returning == false)
		{
			if(persist == false)
			{
				switch(GetDirection())
				{
					case 3:
						SetY(GetY() - (300*elapsed));
					break;

					case 0:
						SetX(GetX() + (300*elapsed));
					break;

					case 2:
						SetY(GetY() + (300*elapsed));
					break;

					case 1:
						SetX(GetX() - (300*elapsed));
					break;
				}
			}
		}
		else
		{
			if(GetX() < GamePlayState::GetInstance()->GetCamX()+Game::GetInstance()->GetScreenWidth()
				&& GetY() < GamePlayState::GetInstance()->GetCamY()+Game::GetInstance()->GetScreenHeight()
				&& GetX() > GamePlayState::GetInstance()->GetCamX()
				&& GetY() > GamePlayState::GetInstance()->GetCamY())
			{
				bool x = false;
				bool y = false;

				if(GetX() + GetWidth() < GetOwner()->GetRect().left)
				{
					SetX(GetX()+(400*elapsed));
				}
				else if(GetX() > GetOwner()->GetRect().right)
				{
					SetX(GetX()-(400*elapsed));
				}
				else
					x = true;
				if(GetY() + GetHeight() < GetOwner()->GetRect().top)
				{
					SetY(GetY()+(400*elapsed));
				}
				else if(GetY() > GetOwner()->GetRect().bottom)
				{
					SetY(GetY()-(400*elapsed));
				}
				else
					y = true;

				if(x && y)
				{
					isSpcAttacking = false;
					returning = false;
					hitEnemy = false;
					render = false;
				}
			}
			else
			{
				isSpcAttacking = false;
				returning = false;
				hitEnemy = false;
				render = false;
			}
		}
	}
	
	
}

void Saw::Render()
{
	CSGD_Direct3D::GetInstance()->GetSprite()->Flush();

	if(GetOwner()->GetCurWeapon() == 1)
	{
		if(render == true)
		{
			CSGD_TextureManager::GetInstance()->Draw(GetTextureID(), int(GetX() - GamePlayState::GetInstance()->GetCamX()), 
				int(GetY() - GamePlayState::GetInstance()->GetCamY()));

			//CSGD_Direct3D::GetInstance()->DrawRect(GetRect(), 255, 0, 0);

		}
	
	}

	hitParticle->Render();
}

RECT Saw::GetRect()
{
	RECT rect = {};
	if(isSpcAttacking == true)
	{
		rect.top	= (LONG)GetY();
		rect.bottom = (LONG)GetY()+GetHeight();
		rect.left	= (LONG)GetX();
		rect.right	= (LONG)GetX()+GetWidth();

		return rect;
	}
	else
	{
		int dir = GetDirection();

		switch(dir)
		{
		case 0:
			{
				rect = MeleeWeapon::GetRect();
				rect.right += 10;
			}
			break;
		case 1:
			{
				rect = MeleeWeapon::GetRect();
				rect.left -= 10;
			}
			break;
		case 2:
			{
				rect = MeleeWeapon::GetRect();
			}
			break;
		case 3:
			{
				rect = MeleeWeapon::GetRect();
			}
			break;
		default:
			{
			}
			break;
		}
		return rect;
	}
}
